package team.kirohuji.controller.tidings;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import team.kirohuji.domain.tidings.Notify;
import team.kirohuji.domain.tidings.Subscription;
import team.kirohuji.repository.jpa.tidings.NotifyRepository;
import team.kirohuji.service.tidings.NotifyService;

@RestController
@RequestMapping("/notify")
public class NotifyController {
	@Autowired
	public NotifyRepository notifyRepository;
	
	@Resource
	public NotifyService notifyService;
	
	//type:1.订阅 2.取消订阅 3.提醒 4.主页公告
	
	@RequestMapping(value = "/announce/group", method = RequestMethod.GET)
	List<Notify> getUnreadRemind() {
		return notifyRepository.findAllByType(4);
	}
	
	@RequestMapping(value = "/{userId}/unread/remind/count", method = RequestMethod.GET)
	long getUnreadRemind(@PathVariable Integer userId) {
		return notifyService.getUnreadRemind(userId);
	}
	@RequestMapping(value = "/{userId}/subscribe/{targetId}/{targetType}", method = RequestMethod.DELETE)
	String cancelSubscription(@PathVariable Integer userId,@PathVariable Integer targetId,@PathVariable String targetType) {
		return notifyService.cancelSubscription(userId, targetId, targetType);
	}
	@RequestMapping(value = "/{userId}/group/subscribe", method = RequestMethod.GET)
	List<Subscription> getSubscription(@PathVariable Integer userId) {
		return notifyService.getSubscription(userId);
	}
	
	@RequestMapping(value = "/{userId}/subscribe/{targetId}/{targetType}/{reasion}", method = RequestMethod.POST)
	String subscribe(@PathVariable Integer userId,@PathVariable Integer targetId,@PathVariable String targetType,@PathVariable String reasion) {
		return notifyService.subscribe(userId, targetId, targetType, reasion);
	}
	
	@RequestMapping(value = "/{senderId}/announce/{topic}/{content}", method = RequestMethod.POST)
	Notify createAnnounce(@PathVariable Integer senderId,@PathVariable String topic,@PathVariable String content) {
		return notifyService.createAnnounce(topic,content, senderId);
	}
	
	@RequestMapping(value = "/{senderId}/remind/{targetId}/{targetType}/{action}/{content}", method = RequestMethod.POST)
	Notify createRemind(@PathVariable Integer senderId,@PathVariable String content,@PathVariable String action,@PathVariable String targetType,@PathVariable Integer targetId) {
		return notifyService.createRemind(targetId, targetType, action, content, senderId);
	}
	@RequestMapping(value = "/{userId}/remind", method = RequestMethod.GET)
	List<Notify> pullRemind(@PathVariable Integer userId) {
		return notifyService.pullRemind(userId);
	}
	@ResponseBody
	@RequestMapping(value = "/{userId}/announce/{topic}", method = RequestMethod.GET)
	Notify pullAnnounce(@PathVariable Integer userId) {
		return notifyService.pullAnnounce(userId);
	}
	/**
	 * Returns the number of entities available. 返回总记录数
	 * 
	 * @return the number of entities
	 */
	/*
	 * @RequestMapping(value = "/count", method = RequestMethod.GET, produces =
	 * "text/plain;charset=UTF-8")
	 */
	@RequestMapping(value = "/count", method = RequestMethod.GET)
	long count() {
		return notifyRepository.count();
	}

	/**
	 * Deletes the entity with the given id. 根据给出的id删除记录
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @throws IllegalArgumentException
	 *             in case the given {@code id} is {@literal null}
	 */
	@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
	void delete(@PathVariable Integer id) {
		notifyRepository.deleteById(id);
	}

	/**
	 * Deletes a given entity. 根据给出的实体删除记录
	 * 
	 * @param entity
	 * @throws IllegalArgumentException
	 *             in case the given entity is (@literal null}.
	 */
	@RequestMapping(value = "", method = RequestMethod.DELETE)
	void delete(@RequestBody Notify entity) {
		notifyRepository.delete(entity);
	}

	/**
	 * Deletes the given entities. 根据给出的一组实体删除一组记录
	 * 
	 * @param entities
	 * @throws IllegalArgumentException
	 *             in case the given {@link Iterable} is (@literal null}.
	 */
	@RequestMapping(value = "/group", method = RequestMethod.DELETE)
	void delete(@RequestBody List<Notify> entities) {
		notifyRepository.deleteAll(entities);
	}

	/**
	 * Deletes all entities managed by the notifyRepository. 根据repository 删除所有的记录
	 */
	@RequestMapping(value = "/all", method = RequestMethod.DELETE)
	void deleteAll() {
		notifyRepository.deleteAll();
	}

	/**
	 * Deletes all entites in a batch call. 删除所有实体记录
	 */
	void deleteAllInBatch() {
		notifyRepository.deleteAllInBatch();
	}

	/**
	 * Deletes the given entities in a batch which means it will create a single
	 * {@link Query}. Assume that we will clear the
	 * {@link javax.persistence.EntityManager} after the call. 进行批量删除
	 * 
	 * @param entities
	 */
	void deleteInBatch(@RequestBody List<Notify> entities) {
		notifyRepository.deleteInBatch(entities);
	}

	/**
	 * Returns whether an entity with the given id exists. 根据给出的id判断对应的实体记录是否存在
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @return true if an entity with the given id exists, {@literal false}
	 *         otherwise
	 * @throws IllegalArgumentException
	 *             if {@code id} is {@literal null}
	 */
	@RequestMapping(value = "/exists/{id}", method = RequestMethod.GET)
	boolean exists(@PathVariable Integer id) {
		return notifyRepository.existsById(id);
	}

	/**
	 * Returns all instances of the type. 返回所有的实体记录
	 * 
	 * @return all entities
	 */
	@RequestMapping(value = "/group", method = RequestMethod.GET)
	List<Notify> findAll() {
		return notifyRepository.findAll();
	}

	/**
	 * Returns all instances of the type with the given IDs. 根据给出的一组id值返回所有对应的实体记录
	 * 
	 * @param ids
	 * @return
	 */
	@RequestMapping(value = "/group/{ids}", method = RequestMethod.GET)
	List<Notify> findAll(String ids) {
		String[] register = ids.split(";");
		List<String> strList = Arrays.asList(register);
		List<Integer> intList = new ArrayList<Integer>();
		for (String str : strList) {
			intList.add(Integer.parseInt(str));
		}
		return notifyRepository.findAllById(intList);
	}

	/**
	 * Returns all entities sorted by the given options. 根据给出的参数返回所有实体记录
	 * 
	 * @param sort
	 * @return all entities sorted by the given options
	 */
	/* @RequestMapping(value = "", method = RequestMethod.GET) */
	/* List<Notify> findAll(Sort sort); */
	/*
	 * List<Notify> findAll(
	 * 
	 * @RequestParam(value = "sortby", required=false,defaultValue = "5") String
	 * sortby,
	 * 
	 * @RequestParam(value = "order", required=false,defaultValue = "5") String
	 * order);
	 */
	/**
	 * Returns a {@link Page} of entities meeting the paging restriction provided in
	 * the {@code Pageable} object. 分页获取数据
	 * 
	 * 分页获取数据
	 * 
	 * @param page
	 *            第几页
	 * @param limit
	 *            每页最长记录数
	 * @return a page of entities
	 */
	@RequestMapping(value = "/page", method = RequestMethod.GET)
	/* Page<Notify> findAll(Pageable pageable) */
	Page<Notify> findAll(@RequestParam(value = "page", defaultValue = "0") Integer page,
			@RequestParam(value = "limit", defaultValue = "5") Integer limit) {
		Sort sort = new Sort(Direction.DESC, "userId");
		Pageable pageable = new PageRequest(page, limit, sort);
		return notifyRepository.findAll(pageable);
	}

	/*
	 * List<Notify> findAll(){
	 * 
	 * List<Notify> findAll(Sort sort);
	 * 
	 * List<Notify> findAll(Iterable<Integer> ids);
	 */

	/**
	 * Retrieves an entity by its id. 根据id取得对应的一个实体记录
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @return the entity with the given id or {@literal null} if none found
	 * @throws IllegalArgumentException
	 *             if {@code id} is {@literal null}
	 */
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	Notify findOne(@PathVariable Integer id) {
		return notifyRepository.getOne(id);
	}

	/**
	 * Flushes all pending changes to the database. 刷新所有到数据库的改变
	 */
	@RequestMapping(value = "/flush", method = RequestMethod.GET)
	void flush() {
		notifyRepository.flush();
	}

	/**
	 * Returns a reference to the entity with the given identifier. 根据给出的id获得一个实体记录
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @return a reference to the entity with the given identifier.
	 * @see EntityManager#getReference(Class, Object)
	 */
	/* Notify getOne(Integer id); */

	/**
	 * Saves a given entity. Use the returned instance for further operations as the
	 * save operation might have changed the entity instance completely.
	 * 保存给出的一个实体，如果实体存在则实体记录会被修改记录，不存在则保存
	 * 
	 * @param entity
	 * @return the saved entity
	 */
	@RequestMapping(value = "", method = RequestMethod.POST)
	Notify save(@RequestBody Notify entity) {
		return notifyRepository.save(entity);
	}

	/**
	 * Saves all given entities. 保存给出的一组实体记录
	 * 
	 * @param entities
	 * @return the saved entities
	 * @throws IllegalArgumentException
	 *             in case the given entity is (@literal null}.
	 */
	@RequestMapping(value = "/group", method = RequestMethod.POST)
	List<Notify> save(@RequestBody List<Notify> entities) {
		return notifyRepository.saveAll(entities);
	}

	/**
	 * Saves an entity and flushes changes instantly. 保存实体记录并且立刻刷新
	 * 
	 * @param entity
	 * @return the saved entity
	 */
	Notify saveAndFlush(Notify entity) {
		return notifyRepository.saveAndFlush(entity);
	}
}
